package com.heima.wemedia.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.threadlocal.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.ShenHeService;
import com.heima.wemedia.service.WmNewsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Date;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private ShenHeService shenHeService;

    /**
     * 查询文章列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult list(WmNewsPageReqDto dto) {
        //1.非空判断
        dto.checkParam();
        //2.分页查询
        IPage<WmNews> page = new Page<>(dto.getPage(), dto.getSize());
        LambdaQueryWrapper<WmNews> queryWrapper = Wrappers.lambdaQuery();
        //2.1 根据状态查询
        if (dto.getStatus() != null) {
            queryWrapper.eq(WmNews::getStatus, dto.getStatus());
        }

        //2.2 根据关键字查询
        if (!StringUtils.isEmpty(dto.getKeyword())) {
            queryWrapper.like(WmNews::getTitle, dto.getKeyword());
        }

        //2.3 根据频道id查询
        if (dto.getChannelId() != null) {
            queryWrapper.eq(WmNews::getChannelId, dto.getChannelId());
        }

        //2.4 根据开始和结束时间查询
        if (dto.getBeginPubdate() != null && dto.getEndPubdate() != null) {
            queryWrapper.between(WmNews::getPublishTime, dto.getBeginPubdate(), dto.getEndPubdate());
        }

        //2.5 根据登录用户id查询
        queryWrapper.eq(WmNews::getUserId, WmThreadLocalUtil.getUser().getId());
        queryWrapper.orderByDesc(WmNews::getCreatedTime);

        page = super.page(page, queryWrapper);

        //3.返回数据结果
        ResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
        result.setData(page.getRecords());
        return result;
    }

    /**
     * 保存-修改-提交草稿为一体的方法
     * 主方法
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public ResponseResult submit(WmNewsDto dto) {
        //TODO

        //设置属性
        WmUser user = WmThreadLocalUtil.getUser();
        WmNews news = WmNews.builder().title(dto.getTitle())
                .content(dto.getContent())
                .type(dto.getType())
                .channelId(dto.getChannelId())
                .labels(dto.getLabels())
                .publishTime(dto.getPublishTime())
                .userId(user.getId())
                .submitedTime(dto.getSubmitedTime())
                .createdTime(Date.valueOf(LocalDate.now()))
                .build();
        //多张图片
        List<String> images = new ArrayList<>();
        String imageString = new String();
        if (1 == dto.getType() || 3 == dto.getType()) {
            for (String image : dto.getImages()) {
                images.add(image);
                if (image.equals(images.get(0))) {
                    imageString = image;
                }
                imageString = imageString + "," + image;
            }
            news.setImages(imageString);
            news.setType(dto.getType());
        }
        //获取内容中的图片
        List<String> connectImages = new ArrayList<>();
        String content = dto.getContent();
        ObjectMapper objectMapper = new ObjectMapper();

        try {
            List<Map<String, String>> result = objectMapper.readValue(content, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, HashMap.class));
            for (Map<String, String> map : result) {
                if ("image".equals(map.get("type"))) {
                    connectImages.add(map.get("value"));
                }
            }
            //图片自动匹配规则
            if (-1 == dto.getType()) {
                //内容中无图 ，不用选择封面图片，则设置为封面是无图结构
                if (connectImages.size() == 0) {
                    news.setType((short) 0);
                }
                //内容中的图片数量大于等于1，小于3，选择1张内容图片作为封面内图片，且设置封面布局方式为单图布局
                if (connectImages.size() >= 1 && connectImages.size() < 3) {
                    news.setType((short) 1);
                    news.setImages(connectImages.get(0));
                }
                //内容中的图片数量大于等于3，选择3张内容图片作为封面图片，且设置封面布局方式为多图布局
                if (connectImages.size() >= 3) {
                    news.setType((short) 3);
                    String connentImgString = new String();
                    for (String connectImage : connectImages.subList(0, 3)) {
                        if (connectImage.equals(connectImages.get(0))) {
                            connentImgString = connectImage;
                        }
                        connentImgString = connentImgString + "," + connectImage;

                    }
                    news.setImages(connentImgString);
                }
            }
            //判断id是否存在
            WmNews wmNews = this.getById(dto.getId());
            if (ObjectUtil.isNotNull(wmNews)) {
                //存在则删除已关联素材关系
                wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery()
                        .eq(WmNewsMaterial::getNewsId, wmNews.getId()));
            }
            //判断是否为草稿
            //是草稿
            if (0 == dto.getStatus()) {
                news.setStatus(dto.getStatus());
                return ResponseResult.okResult("草稿保存完成");
            }
            //新增或修改文章
            news.setStatus(dto.getStatus());
            this.saveOrUpdate(news);
            //不是则继续操作
            //关联内容中的图片与文章的关系
            if (connectImages != null && connectImages.size() > 0) {
                List<Integer> materialIds = new ArrayList<>();
                for (String connectImage : connectImages) {
                    List<WmMaterial> wmMaterial = wmMaterialMapper.selectList(Wrappers.<WmMaterial>lambdaQuery()
                            .eq(WmMaterial::getUrl, connectImage));
                    for (WmMaterial material : wmMaterial) {
                        materialIds.add(material.getId());
                    }
                }
                wmNewsMaterialMapper.saveRelations(materialIds, news.getId(), (short) 0);
            }
            //关联封面中的图片与文章的关系
            if (images != null && images.size() > 0) {
                List<Integer> materialIds = new ArrayList<>();
                for (String image : images) {
                    List<WmMaterial> wmMaterial = wmMaterialMapper.selectList(Wrappers.<WmMaterial>lambdaQuery()
                            .eq(WmMaterial::getUrl, image));
                    for (WmMaterial material : wmMaterial) {
                        materialIds.add(material.getId());
                    }
                }
                wmNewsMaterialMapper.saveRelations(materialIds, news.getId(), (short) 1);
            }
            shenHeService.shenHe(dto);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        //6.返回数据
        return ResponseResult.okResult("发布文章完成");
    }

    /**
     * 文章上下架
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult downOrUp(WmNewsDto dto) {
        //TODO
        this.update(Wrappers.<WmNews> lambdaUpdate().eq(WmNews::getId,dto.getId())
                .set(WmNews::getEnable,dto.getEnable()));
        return ResponseResult.okResult("文章上下架完成");
    }
}
